from common.context.global_context import GlobalContext
from database.mapper import stock_info
from utils import statisticalutil, parse_util


# 计算周期
# 加权(n段加权) 按照每年流失10%指数计算权重[1, 0.9, 0.81, 0.66, 0.43, 0.18, 0.03]
def cal_period_weight(glc: GlobalContext):
    macd_all = glc.get_all_macd()
    len_macd_all = len(macd_all)
    beg_index = 0  # 起始位置
    for i in range(len_macd_all - 1):
        if macd_all[i].get('macd') * macd_all[i + 1].get('macd') or macd_all[i].get('macd') == 0:
            beg_index = i + 1
            break

    period_dict = {}
    for i in range(max(int(len_macd_all / 260), 1)):
        for j in range(260):
            print('')

    flag: int = -1
    if macd_all[0].get('macd') > 0:
        flag = 1
    period = 0
    period_list = []
    negative = 0
    positive = 0
    for i in range(1, len(macd_all)):
        period += 1
        macd = macd_all[i].get('macd')
        if macd < 0:
            negative += 1
        elif macd > 0:
            positive += 1
        if (macd > 0 and flag == -1) or (macd < 0 and flag == 1):
            flag = round(flag * 2)
        elif (macd < 0 and flag == -2) or (macd > 0 and flag == 2):
            flag = round(flag / 2)
            period_list.append({'period': period, 'rq': macd_all[i].get('rq')})
            period = 0
    p_len = len(period_list)
    period_list_sorted = sorted(period_list, key=lambda x: x['period'])
    critical_num = statisticalutil.mean(parse_util.list_dict_to_list(period_list_sorted[0:int(p_len / 3)], 'period'))
    format_period(period_list, critical_num)
    period_list_new = []
    for i in range(p_len):
        if period_list[i].get('period') > critical_num:
            period_list_new.append(period_list[i])

    glc.result_dict_put('period', statisticalutil.mean(parse_util.list_dict_to_list(period_list_new, 'period')))
    glc.result_dict_put('lsxs', statisticalutil.discrete_value(parse_util.list_dict_to_list(period_list_new, 'period')))
    glc.result_dict_put('negative', negative)
    glc.result_dict_put('positive', positive)
    glc.result_dict_put('np', round(negative / positive * 100))
    return period_list_new


# 计算周期
# 加权(n段加权)[1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0]
# 加权(n段加权) 按照每年流失10%指数计算权重[1, 0.9, 0.81, 0.66, 0.43, 0.18, 0.03]
def cal_period(glc: GlobalContext):
    macd_all = glc.get_all_macd()
    flag: int = -1
    if macd_all[0].get('macd') > 0:
        flag = 1
    period = 0
    period_list = []
    negative = 0
    positive = 0
    for i in range(1, len(macd_all)):
        period += 1
        macd = macd_all[i].get('macd')
        if macd < 0:
            negative += 1
        elif macd > 0:
            positive += 1
        if (macd > 0 and flag == -1) or (macd < 0 and flag == 1):
            flag = round(flag * 2)
        elif (macd < 0 and flag == -2) or (macd > 0 and flag == 2):
            flag = round(flag / 2)
            period_list.append({'period': period, 'rq': macd_all[i].get('rq')})
            period = 0
    p_len = len(period_list)
    period_list_sorted = sorted(period_list, key=lambda x: x['period'])
    critical_num = statisticalutil.mean(parse_util.list_dict_to_list(period_list_sorted[0:int(p_len / 3)], 'period'))
    format_period(period_list, critical_num)
    period_list_new = []
    for i in range(p_len):
        if period_list[i].get('period') > critical_num:
            period_list_new.append(period_list[i])

    glc.result_dict_put('period', statisticalutil.mean(parse_util.list_dict_to_list(period_list_new, 'period')))
    glc.result_dict_put('lsxs', statisticalutil.discrete_value(parse_util.list_dict_to_list(period_list_new, 'period')))
    glc.result_dict_put('negative', negative)
    glc.result_dict_put('positive', positive)
    glc.result_dict_put('np', round(negative / (negative + positive) * 100))
    return period_list_new


# 修复周期
# 筛选出小的周期合并到两次周期小的一个周期
# 筛选方案：min(前1/3小的周期的平均值,10)
def format_period(period_list: list, critical_num):
    p_len = len(period_list)
    for i in range(1, p_len - 1):
        p0 = period_list[i - 1]
        p1 = period_list[i]
        p2 = period_list[i + 1]
        if p1.get('period') < critical_num:
            if p0.get('period') > p2.get('period'):
                p2['period'] += p1.get('period')
            else:
                p0['period'] += p1.get('period')


if __name__ == '__main__':
    print('test')
    # period_list = cal_period(GlobalContext('601600'))
    ss = stock_info.select_all()
    for s in ss:
        gc = GlobalContext(s.code)
        cal_period(gc)
        print(s.name + ' 周期:' + str(gc.result.get('period')) + ' np:' + str(gc.result.get('np')))
    print('end')
